
//
//	This file tests reporting of E200X errors and W200X warnings
//


//
// E2001, W2001: Assignment to undefined variable
//

doTest([
	'a = 1;'
], [
	[2001, 1, 1, 0]
]);

doTest([
	'print(1 + (a = 1));'	// inside expression
], [
	[2001, 1, 12, 0]
]);

doTest([
	'var a = 1;'
], []);

doTest([
	'var a;\n' +
	'a = 1;'
], []);


doTest([
	'var o = {};\n' +
	'o.a = 1;'
], []);

doTest([
	'var x = y = 1;'
], [
	[2001, 1, 9, 0]
]);

doTest([
	'for (a in b);'
], [
	[2001, 1, 6, 0]
]);

doTest([
	'for (var a in b);'
], []);

doTest([
	'for (a = 1;;);'
], [
	[2001, 1, 6, 0]
]);

doTest([
	'for (var a = 1;;);'
], []);

doTest([
	'x = 1; function a() {\n' +
		'var x = 2;\n' +
	'}'
], [
	[2001, 1, 1, 0]
]);

doTest([
	'function a() {\n' +
		'x = 1;\n' +
	'}\n' +
	'function b() {\n' +
		'var x = 2;\n' +
	'}'
], [
	[2001, 2, 1, 0]
]);

doTest([
	'function a() {\n' +
		'x = 1;\n' +
	'}\n' +
	'var x = 2;'
], []);

doTest([
	'var a = { set asdf(x) { y = 1; }}'
], [
	[2001, 1, 25, 0]
]);

// setter arguments must not be marked as undeclared
doTest([
	'var a = { set asdf(x) { x = 1; }}'
], []);

//
// E2002, W2002: "with" statements are not allowed in strict mode
//

doTest([
	'with (window) {}'
], [
	[2002, 1, 1, 0]
]);


//
// E2003, W2003: A property, getter or setter with this name already exists in the object.
//

doTest([
	'({ a: 1, get a(){} });'
], [
	[2003, 1, 14, 0]
]);

doTest([
	'({ a: 1, set a(newValue){} });'
], [
	[2003, 1, 14, 0]
]);

doTest([
	'({ get a(){}, get a(){} });'
], [
	[2003, 1, 19, 0]
]);

doTest([
	'({ set a(newValue){}, set a(newValue){} });'
], [
	[2003, 1, 27, 0]
]);

doTest([
	'({ get a(){}, set a(newValue){} });'
], []);

doTest([
	'({ a: 1, a: 2 });'
], [
	[2003, 1, 10, 0]
]);

doTest([
	'({ a: 1, "a": 2 });'
], [
	[2003, 1, 10, 0]
]);

doTest([
	'({ "a": 1, \'a\': 2 });'
], [
	[2003, 1, 12, 0]
]);

doTest([
	'({ "aa": 1, "a\\u0061": 2 });'
], [
	[2003, 1, 13, 0]
]);

doTest([
	'({ a: 1, \'a\': 2 });'
], [
	[2003, 1, 10, 0]
]);

doTest([
	'({ 1: 1, "1": 2 });'
], [
	[2003, 1, 10, 0]
]);


//
// E2004, W2004: In strict mode, the identifiers "eval" and "arguments" may not be used for function arguments or variable names
//

doTest([
	'var eval;'
], [
	[2004, 1, 5, 0]
]);

doTest([
	'function eval(){};'
], [
	[2004, 1, 10, 0]
]);

doTest([
	'(function (eval){});'
], [
	[2004, 1, 12, 0]
]);

doTest([
	'var a = eval();'
], []);

doTest([
	'var eval1;'
], []);


//
// E2005, W2005: In strict mode, two arguments for a function must not have the same name.
//

doTest([
	'(function (a, a){});'
], [
	[2005, 1, 15, 0]
]);

doTest([
	'(function (a, b){});'
], []);


//
// E2006, W2006: In strict mode, octal numbers and octal escapes in strings are not allowed.
//

doTest([
	'02;'
], [
	[2006, 1, 1, 0]
]);

doTest([
	'-02;'
], [
	[2006, 1, 2, 0]
]);

doTest([
	'2;'
], []);

doTest([
	'"\\251";'
], [
	[2006, 1, 1, 0]
]);

doTest([
	'"\\xA9";'
], []);

doTest([
	'"\\u00A9";'
], []);

doTest([
	'"\\0";'	// allowed
], []);


//
// E2007, W2007: In strict mode, the operand after a "delete" instruction cannot be a direct reference to a variable, function argument, or function name.
//

doTest([
	'delete a;'
], [
	[2007, 1, 8, 0]
]);

doTest([
	'delete a.b;'
], []);

doTest([
	'delete 3;'
], []);
